这个解法效率一般,在cpp里算是中档水平。但我觉得非常简单易懂。
数独的规则非常明了:
于是我对应这三个规则设计了三个 hash 表:
std::unordered_map<size_t, std::unordered_set> row_map, col_map, cel_map;
// ^ ^ ^ 1 ^ 2 ^ 3
// index of row/col/cell have shown number.
好的数据结构,可以大面积缩短算法描述,在这道题里展现的淋漓尽致。这三个 hash 表一出,我想接下来应该无需赘述了吧。
遍历整个 board,insert 到相应的 hash
表中,如果遇到插入失败的, return false
即可。
唯一值得一提的是,cell 其实是没有 index 的,这个只需要自己制定一个规则即可。我制定的是:
size_t cell_index = i/3 * 10 + j/3;
// 那么9个 cell 的 index 依次为:0, 1, 2, 10, 11, 12, 20, 21, 22.
从这道题可以看出 C++ Primer 5th 的经典,因为同样的思路和代码,出现在昨晚我提交的课后习题里。。。
#include <vector>
#include <unordered_map>
#include <unordered_set>
using std::vector;
class Solution {
public:
bool isValidSudoku(vector<vector<char> > &board) {
std::unordered_map<size_t, std::unordered_set<char>> row_map, col_map, cel_map;
for (size_t i=0; i<board.size(); ++i)
for (size_t j=0; j<board[0].size(); ++j) {
if (board[i][j] == '.') continue;
if (!row_map[i].insert(board[i][j]).second) return false;
if (!col_map[j].insert(board[i][j]).second) return false;
if (!cel_map[i/3 * 10 + j/3].insert(board[i][j]).second) return false;
}
return true;
}
};